/**
 ****************************************************************
 *
 * description : 带限制的电机控制模块
 * version     : V1.1
 * Revision    : V1.1 将以前的MSG与InSpeed,整理成统一的函数
 * 			     V1.0 增加带速度控制的功能
 * Author      : DJM <d.jiaming@qq.com>
 *
 ****************************************************************
 */
#ifndef _MODULE_MC_WITHLIMITED_
#define _MODULE_MC_WITHLIMITED_
#ifdef __cplusplus
 extern "C" {
#endif
#include "stdint.h"
#include "RTL.h"

#define MCWL_Constrain(input,min,max) \
	do \
	{ \
		if (input <= min)      \
			input = min;       \
		else if(input >= max)  \
			input = max;       \
		else input = input;    \
	} while (0);
#define MCWL_ABS(n) ((n)>0?(n):(0-(n)))
#define Gettime() os_time_get()

//#define OpposeToTest 1
typedef struct Encoder_Stuct
{
	int16_t Speed;
	long Position;
	int last_position,last_coder,this_coder,turn_cnt;
}EncoderStuct;

typedef enum
{
	MCWL_ToZero = 0,
	MCWL_OpposeZero,
} MCWL_DirTypeDef;

typedef enum
{
	MCWL_ERROR_OK = 0,
	MCWL_ERROR_ERROR,
	MCWL_ERROR_BUSY,
	MCWL_ERROR_READY,
	MCWL_ERROR_TIMEOUT,
} MCWL_ERRORTypeDef;
typedef enum
{
	MCWL_RESET = 0,
	MCWL_BUSY,
	MCWL_READY,
	MCWL_LOCKED,
} MCWL_StatusTypeDef;
typedef enum
{
	MCWL_ZeroInit_Selfcheck = 0,
MCWL_ZeroInit_1stIsOn,
	MCWL_ZeroInit_1stIsOff,
	MCWL_SwitchCheckFail,
	MCWL_UserCmd_Reset,
	MCWL_UserCmd_OpposeZero,
#if OpposeToTest
	MCWL_ZeroInit_OpposeToZero,
#endif
	MCWL_ZeroInit_Ready

} MCWL_ZeroInitStatusTypeDef;

typedef enum
{
	MCWL_OFF = 0,
	MCWL_ON
} MCWL_JudgmentStatusTypeDef;

typedef enum
{
	Primary_Top = 0,
	Primary_Bottom,
	Secondary_Top,
	Secondary_Bottom,
	Not_EndPoint,
}Photoelectric_StatusTypeDef;//光电开关状态



typedef struct
{
	int32_t MinLimit;
	int32_t MaxLimit;
	int32_t MinLimitReferToZero;
	int32_t MaxLimitReferToZero;
	int32_t DeadZone;
	int32_t DangerousZone;
	uint32_t DangerousZoneTimeout;
	void  (* MotorOperate)( int32_t argument);
	int32_t  (* GetMotorPosition)(void);
	void  (* MotorStop)( void );
	void  (* MotorIdle)( void );


}MCWL_InitTypeDef;

typedef enum 
{
  GoToGround = -2147483647,
	OpposeToGround = 2147483647
}MCWL_Direction_Typedef;

typedef struct
{
	MCWL_ZeroInitStatusTypeDef state;
	int32_t SpeedToZero;
	uint32_t TimeoutToZero;
	int32_t BackwardToZero;

	int32_t SpeedOpposeZero;
	uint32_t TimeoutOpposeZero;
	int32_t BackwardOpposeZero;
	MCWL_Direction_Typedef Direction;
	MCWL_JudgmentStatusTypeDef (* ToZeroStatus)( void );
	MCWL_JudgmentStatusTypeDef (* ToOpposeZeroStatus)( void );
}MCWL_ZeroInitTypeDef;


typedef struct
{
//	MCWL_JudgmentStatusTypeDef (* JudgmentFunc)( void );
	int32_t Position;
	int32_t Speed;
	uint32_t Timeout;
	uint32_t Level;
	MCWL_JudgmentStatusTypeDef state;
	MCWL_DirTypeDef Dir;
}MCWL_MsgTypeDef;

typedef struct
{

	MCWL_DirTypeDef Dir;
	MCWL_InitTypeDef Init;
	MCWL_ZeroInitTypeDef ZeroInit;
	
	int32_t ZeroOffset;
	int32_t TargetPosition;
	int32_t CurrentLevel;
	uint32_t Timeout;
	uint32_t DZ_Timeout;
	MCWL_StatusTypeDef state;
	MCWL_MsgTypeDef MSG;
}MCWL_HandleTypeDef;




MCWL_ERRORTypeDef MCWL_Init(MCWL_HandleTypeDef *phmotor);
MCWL_ERRORTypeDef MCWL_Exec(MCWL_HandleTypeDef *phmotor);

void MCWL_SetUserCmd(MCWL_HandleTypeDef *phmotor,MCWL_ZeroInitStatusTypeDef Cmd);

void MCWL_MSG_Set(MCWL_HandleTypeDef *phmotor,int32_t position,int32_t speed,uint32_t level);
void MCWL_MSG_SetTimeout(MCWL_HandleTypeDef *phmotor,int32_t position,int32_t speed,uint32_t level,uint32_t timeout);
void MCWL_Calculate(MCWL_HandleTypeDef *phmotor,int32_t pos,int32_t speed);


void Set_Encoder(EncoderStuct *pEncoder,int32_t cEncoder);


#ifdef __cplusplus
}
#endif

#endif
